import re
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# ... (matplotlib中文设置不变) ...
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


def parse_log_with_mfe_mae(file_path):
    """
    解析包含MAE和MFE信息的最终版日志。
    """
    try:
        with open(file_path, 'r', encoding='UTF-8') as f:
            content = f.read()
    except FileNotFoundError:
        print(f"错误：找不到文件 {file_path}")
        return None

    blocks = content.split('=========\n')

    open_positions = {}
    completed_trades = []

    id_pattern = re.compile(r"├─ 仓位ID : ([\w-]+)")
    symbol_pattern = re.compile(r"├─ 交易品种: (\S+)")
    close_reason_pattern = re.compile(r"平仓原因: (.*)")
    pnl_pattern = re.compile(r"├─ 本笔盈亏: ([-\d.]+)")
    mae_pattern = re.compile(r"MAE: ([\d.]+)%")
    mfe_pattern = re.compile(r"MFE: ([\d.]+)%")

    for block in blocks:
        id_match = id_pattern.search(block)
        if not id_match: continue
        position_id = id_match.group(1)

        if "[开仓做" in block:
            symbol_match = symbol_pattern.search(block)
            if symbol_match:
                open_positions[position_id] = {'symbol': symbol_match.group(1)}

        elif "[平仓" in block or "[止损" in block:
            if position_id in open_positions:
                pnl_match = pnl_pattern.search(block)
                reason_match = close_reason_pattern.search(block)

                if pnl_match and reason_match:
                    trade_data = open_positions.pop(position_id)
                    trade_data['pnl'] = float(pnl_match.group(1))

                    reason_text = reason_match.group(1)
                    mae_match = mae_pattern.search(reason_text)
                    mfe_match = mfe_pattern.search(reason_text)

                    if mae_match and mfe_match:
                        trade_data['mae'] = float(mae_match.group(1))
                        trade_data['mfe'] = float(mfe_match.group(1))
                        completed_trades.append(trade_data)

    if not completed_trades:
        print("警告：未能解析出任何包含MAE和MFE的完整交易。")
        return pd.DataFrame()

    return pd.DataFrame(completed_trades)


def analyze_mfe_mae_plot(df):
    """
    进行MFE/MAE分析并绘制核心散点图。
    """
    if df.empty or 'mae' not in df.columns or 'mfe' not in df.columns:
        print("数据不足，无法进行MFE/MAE分析。")
        return

    df['盈利情况'] = np.where(df['pnl'] > 0, '盈利', '亏损')

    # 计算平均止损（假设亏损单的MAE近似于止损距离）和平均止盈（盈利单的PNL）
    # 注意：这里的 '止损' 是近似值，用于在图上画参考线
    avg_stop_loss_mae = df[df['盈利情况'] == '亏损']['mae'].mean()
    avg_take_profit_pnl_percent = df[df['盈利情况'] == '盈利']['pnl'].sum() / df[df['盈利情况'] == '盈利']['pnl'].abs().sum() * df[df['盈利情况'] == '盈利']['mfe'].mean() if len(df[df['盈利情况'] == '盈利']) > 0 else 0

    plt.figure(figsize=(16, 12))

    winners = df[df['盈利情况'] == '盈利']
    losers = df[df['盈利情况'] == '亏损']

    plt.scatter(winners['mae'], winners['mfe'], color='green', alpha=0.6, label=f'盈利交易 ({len(winners)}笔)')
    plt.scatter(losers['mae'], losers['mfe'], color='red', alpha=0.6, label=f'亏损交易 ({len(losers)}笔)')

    # 绘制参考线
    max_val = max(df['mae'].max(), df['mfe'].max())
    plt.plot([0, max_val], [0, max_val], 'b--', label='盈亏平衡线 (MAE = MFE)')

    if not np.isnan(avg_stop_loss_mae):
        plt.axvline(avg_stop_loss_mae, color='darkred', linestyle=':', linewidth=2, label=f'平均亏损MAE (近似止损): {avg_stop_loss_mae:.2f}%')
    if avg_take_profit_pnl_percent > 0:
        plt.axhline(avg_take_profit_pnl_percent, color='darkgreen', linestyle=':', linewidth=2, label=f'平均盈利MFE: {avg_take_profit_pnl_percent:.2f}%')

    plt.title('MFE vs. MAE 分布图 ("交易GPS")', fontsize=20)
    plt.xlabel('最大不利变动 (MAE) % - 风险暴露/回撤', fontsize=14)
    plt.ylabel('最大有利变动 (MFE) % - 潜在盈利', fontsize=14)
    plt.legend(fontsize=12)
    plt.grid(True, which='both', linestyle='--', linewidth=0.5)
    plt.xlim(left=0)
    plt.ylim(bottom=0)

    # 添加区域解读文字
    plt.text(max_val * 0.05, max_val * 0.9, '区域1: 理想的盈利单\n(低风险, 高回报)', fontsize=12, color='darkgreen')
    plt.text(max_val * 0.05, max_val * 0.1, '区域2: 被快速止损的单', fontsize=12, color='darkred')
    plt.text(max_val * 0.6, max_val * 0.1, '区域3: “死扛”型亏损单', fontsize=12, color='purple')
    plt.text(max_val * 0.6, max_val * 0.9, '区域4: “过山车”型盈利单', fontsize=12, color='blue')

    plt.show()


# --- 主程序 ---
if __name__ == "__main__":
    file_path = '回测结果 (2).txt'
    trades_df = parse_log_with_mfe_mae(file_path)

    if trades_df is not None and not trades_df.empty:
        analyze_mfe_mae_plot(trades_df)
    else:
        print("未能加载或解析数据，分析终止。")